'''
Game Boy ROM Object
A part of the libPirate (Python) library

Author:    Derrick Sobodash <derrick@cinnamonpirate.com>
Copyright: (c) 2006, 2007, 2008, 2009 Derrick Sobodash
Web site:  http://libpirate.org/
License:   BSD License <http://opensource.org/licenses/bsd-license.php>
'''

try:
	import re
	import pirstring
	from struct import *
	from time import mktime
	import sys

except ImportError, err:
	print "Could not load %s module." % (err)
	raise SystemExit

'''
object RomGboy(data)

An object representation of a Virtual Boy ROM image.
	
The object contains a Virtual Boy ROM image with member variables and methods
to store and edit the game's internal header.

Inherits the libPirate File Stream functions.
'''
class RomGboy(object):
	## Binary blob
	_blob = "\xce\xed\x66\x66\xcc\x0d\x00\x0b\x03\x73\x00\x83\x00\x0c\x00\x0d" + \
	        "\x00\x08\x11\x1f\x88\x89\x00\x0e\xdc\xcc\x6e\xe6\xdd\xdd\xd9\x99" + \
					"\xbb\xbb\x67\x63\x6e\x0e\xec\xcc\xdd\xdc\x99\x9f\xbb\xb9\x33\x3e"
	
	## Contains a tuple of all cart types
	_cart = (
	    "ROM Only",                     "ROM + MBC1",
			"ROM + MBC1 + RAM",             "ROM + MBC1 + RAM + Battery",
			"ROM + MBC2",                   "ROM + MBC2 + Battery",
			"",
	
	## Contains a tuple of all known Nintendo licensees.
	_maker = ("Invalid[00]",
			'Nintendo',               'Ajinomoto',                'Imagineer-Zoom',
			'Electronic Arts',        'Zamuse',                   'Falcom',
			'Infogrames',             'Capcom',                   'HOT B Co. Ltd',
			'Jaleco',                 'Coconuts',                 'Coconuts Japan',
			'Micronet',               'Technos',                  'Mebio Software',
			'Shouei'     ,            'Starfish',                 'Gremlin Graphics',
			'Electronic Arts',        'NCS',                      'Cobra Team',
			'Human/Field',            'KOEI',                     'Hudson Soft',
			'Sheisha/Kousaka Koji',   'Yanoman/Max Entertainment','Unknown[27]',
			'Tecmo',                  'Nippon Clary Business',    'Open System',
			'Virgin Games',           'KSS/Rumic Soft',           'Sunsoft',
			'POW',                    'Micro World',              'Bullet-Proof Software',
			'San-X',                  'Enix',                     'Loriciel/Electro Brain',
			'Kemco/Kotobuki System',  'Seta',                     'Culture Brain',
			'Irem',                   'Sotsu Agency',             'Visit',
			'INTEC',                  'System Sacom',             'Viacom International',
			'Carrozzeria',            'Dynamic',                  'Unknown[51]',
			'Magifact',               'Hect',                     'Unknown[54]',
			'Unknown[55]',            'Capcom/Laguna Games',      'Nintendo',
			'Unknown[58]',            'Arcade Zone',              'Empire Software',
			'Loriciel',               'Gremlin Graphics',         'Unknown[63]',
			'Seika',                  'UBI Soft',                 'Unknown[66]',
			'Unknown[67]',            'Life Fitness',             'Gremlin',
			'System 3',               'Spectrum Holobyte',        'Unknown[72]',
			'Irem',                   'Unknown[74]',              'Raya Systems',
			'Renovation Products',    'Malibu Games',             'Unknown[78]',
			'U.S. Gold',              'Absolute Entertainment',   'Acclaim',
			'Activision',             'American Sammy',           'GameTek',
			'Hi-Tech Expressions',    'LJN Toys',                 'Matchbox International',
			'Mattel',                 'Unknown[89]',              'Mindscape',
			'Romstar',                'Imagineer',                'Tradewest/Williams Entertainment',
			'Unknown[94]',            'American Softworks Corp.', 'Titus',
			'Virgin Games',           'Maxis',                    'Origin',
			'Unknown[100]',           'Playmates Entertainment',  'Unknown[102]',
			'Ocean',                  'Unknown[104]',             'Electronic Arts',
			'Unknown[106]',           'Laser Beam',               'Unknown[108]',
			'Unknown[109]',           'Elite',                    'Electro Brain',
			'Infogrames',             'Interplay',                'JVC/LucasArts',
			'Parker Brothers.',       'Konami',                   'Storm/The Sales Curve',
			'Unknown[118]',           'Unknown[119]',             'T*HQ Software',
			'Accolade',               'Triffix Entertainment',    'Unknown[123]',
			'Microprose',             'Unknown[125]',             'Unknown[126]',
			'Kemco',                  'Misawa Entertainment',     'Teichiku Co. Ltd.',
			'Namco',                  'Lozc',                     'KOEI',
			'Unknown[133]',           'Tokuma Shoten Intermedia', 'Tsukuda Original',
			'DATAM-Polystar',         'Unknown[137]',             'Unknown[138]',
			'Bullet-Proof Software',  'Vic Tokai',                'Unknown[141]',
			'Character Soft',         "I'Max",                    'Takara',
			'Chun Soft',              'Video System',             'BEC',
			'Unknown[148]',           'Varie',                    "Yonezawa/S'Pal",
			'Kaneco',                 'Unknown[152]',             'Pack-In-Video',
			'Nichibutsu',             'Tecmo',                    'Imagineer',
			'Unknown[157]',           'Unknown[158]',             'Nova Co.,Ltd',
			'Telenet',                'Hori Electric',            'Unknown[162]',
			'TGL',                    'Konami',                   'K.Amusement Leasing Co.',
			'Kawada',                 'Takara',                   'Unknown[168]',
			'Technos Japan',          'JVC/LucasArts',            'Unknown[171]',
			'TOEI Animation',         'Toho',                     'Unknown[174]',
			'Namco',                  'Probe Entertainment',      'ASCII Co.',
			'Bandai',                 'Pioneer LDC',              'Enix',
			'Unknown[181]',           'Halken',                   'SNK',
			'Unknown[184]',           'Pony Canyon',              'Culture Brain',
			'Sunsoft',                'Toshiba EMI',              'Sony Imagesoft',
			'Unknown[190]',           'Sammy',                    'Taito',
			'Unknown[193]',           'Kemco',                    'SquareSoft',
			'Tokuma Soft',            'Data East',                'Tonkin House',
			'Unknown[199]',           'KOEI',                     'UPL Co.,Ltd.',
			'Konami',                 'NTVIC/VAP',                'USE Co.,Ltd.',
			'Meldac',                 'Pony Canyon',              'Sotsu Agency/Sunrise',
			'Disco/Taito',            'Sofel',                    'Quest',
			'Sigma',                  'ASK Kodansha',             'Unknown[213]',
			'Naxat',                  'Copia System',             'Capcom',
			'Banpresto',              'Tomy',                     'Acclaim',
			'Unknown[220]',           'NCS',                      'Human',
			'Altron',                 'Jaleco',                   'Gaps Inc.',
			'Yutaka',                 'Varie',                    'T&ESoft',
			'Epoch',                  'Unknown[230]',             'Athena',
			'Asmik',                  'Natsume',                  'King Records',
			'Atlus',                  'Sony Music Entertainment', 'Unknown[237]',
			'IGS',                    'Unknown[239]',             'A Wave, Inc',
			'Motown Software',        'Left Field Entertainment', 'Beam Software',
			'Tec Magik',              'Unknown[245]',             'Unknown[246]',
			'Unknown[247]',           'YuMedia',                  'Cybersoft',
			'Unknown[250]',           'Psygnosis',                'Unknown[252]',
			'Unknown[253]',           'Davidson',                 'Hudson Soft'
		)

	'''
	object RomGboy(data)
	
	Initialize the object from given data. Returns False if data is not
	found to be a Game Boy binary.
	'''
	def __init__(self, data):
		
		## Check for a header. If present, remove and store it.
		if len(data) % 0x400 == 0x200:
			self._header = data[0:0x200]
			data = data[0x200: ]
		
		self._data      = data
		self._infoblock = 0x100
	
	'''
	bool isbootable()
	
	Returns the ROM code.
	'''
	def getcode(self):
		if self._data[self._infoblock:self._infoblock + 0x34] != self._blob:
			return(True)
		else:
			return(False)
	
	'''
	string getname()
	
	Returns the name of the ROM image.
	'''
	def getname(self):
		return(self._data[self._infoblock + 0x34:self._infoblock + 0x42].rstrip())
	
	'''
	bool setname(name)
	
	Sets the name of the ROM image.
	'''
	def setname(self, name):
		name = name.ljust(0x14, " ")
		name = name[0:0xf]
		self._data = pirstring.strsub(self._data, self._infoblock + 0x34, name)
		return(True)
	
	'''
	int getrevision()
	
	Returns the ROM's revision number.
	'''
	def getrevision(self):
		return(ord(self._data[self._infoblock + 0x4c]));
	
	'''
	bool setrevision(number)
	
	Sets the ROM's revision number.
	'''
	def setrevision(self, number):
		if number > 255:
			return(False)
		self._data = pirstring.strsub(self._data, self._infoblock + 0x4c, chr(number))
		return(True)
	
	'''
	string getmaker()
	
	Returns a string with the ROM's maker/licensee.
	'''
	def getmaker(self):
		code = ord(self._data[self._infoblock + 0x4b])
		if code == 0x33:
			if re.compile("[A-F0-9][A-F0-9]").match(code) != None:
				return(self._maker[int(code, 16)])
			else:
				return(False)
		else:
			return(self._maker[int(code, 16)])

	'''
	bool setmaker(maker)
	
	Sets the ROM's maker from an input integer 0-255.
	'''
	def setmaker(self, maker):
		if maker > 255 == True:
			return(False)
		if ord(self._data[self._infoblock + 0x2a]) == 0x33:
			self._data = pirstring.strsub(self._data, self._infoblock + 0x44, hex(maker)[2: ])
		else:
			self._data = pirstring.strsub(self._data, self._infoblock + 0x4b, chr(maker))
		return(True)
	


